<script lang="ts">
import { Options, Prop, Vue, Watch } from 'vue-property-decorator';
import { AreaService } from '@jctech/api/services/area';
import { isNullOrWhiteSpece } from '@jctech/utils/is';

const AreaSrc = AreaService.getInstance<AreaService>();

@Options({
  name: 'c-area'
})
export default class CArea extends Vue {
  @Prop() declare firstnode: string;
  @Prop({ default: '' })
  declare modelValue: string;

  @Prop({ type: Number, default: 5 })
  declare showLevel: number;

  @Prop({ type: Number, default: 1 })
  declare type: number;

  areaVm = {
    province: '',
    city: '',
    area: '',
    town: '',
    village: ''
  };

  source: any = {
    provinceLst: [],
    cityLst: [],
    areaLst: [],
    townLst: [],
    villageLst: []
  };

  get myvalue() {
    // 判断是否合法数值
    if (isNullOrWhiteSpece(this.areaVm.province)) {
      return '';
    }
    if (!this.areaVm.city.startsWith(this.areaVm.province)) {
      this.areaVm.city = this.areaVm.area = this.areaVm.town = this.areaVm.village = '';
      return this.areaVm.province;
    }
    if (!this.areaVm.area.startsWith(this.areaVm.city)) {
      this.areaVm.area = this.areaVm.town = this.areaVm.village = '';
      return this.areaVm.city;
    }
    if (!this.areaVm.town.startsWith(this.areaVm.area)) {
      this.areaVm.town = this.areaVm.village = '';
      return this.areaVm.area;
    }
    if (!this.areaVm.village.startsWith(this.areaVm.town)) {
      this.areaVm.village = '';
      return this.areaVm.town;
    }
    return this.areaVm.village;
  }

  mounted() {
    this._getProvince();
    // 初始化
    this.OnChangeValue(this.modelValue, null);
  }

  provinceChange(value) {
    this.areaVm.province = value;
    if (this.type === 2) {
      (this.$refs.child as any).changeTab(1);
    }
  }

  cityChange(value) {
    this.areaVm.city = value;
    if (this.type === 2) {
      (this.$refs.child as any).changeTab(2);
    }
  }

  areaChange(value) {
    this.areaVm.area = value;
    if (this.type === 2) {
      (this.$refs.child as any).changeTab(3);
    }
  }

  townChange(value) {
    this.areaVm.town = value;
    if (this.type === 2) {
      (this.$refs.child as any).changeTab(4);
    }
  }

  villageChange(value) {
    this.areaVm.village = value;
  }

  // 清理不匹配的数据源
  clearAreaSource() {
    if (isNullOrWhiteSpece(this.areaVm.province)) {
      this.source.cityLst = [];
    }
    if (isNullOrWhiteSpece(this.areaVm.city)) {
      this.source.areaLst = [];
    }
    if (isNullOrWhiteSpece(this.areaVm.area)) {
      this.source.townLst = [];
    }
    if (isNullOrWhiteSpece(this.areaVm.town)) {
      this.source.villageLst = [];
    }
  }

  @Watch('modelValue')
  OnChangeValue(v: string, o: string) {
    if (String(v) === String(o)) {
      return;
    }
    // 如果不相等，将数据源重新赋值
    if (!v) {
      this.areaVm.province = this.areaVm.city = this.areaVm.area = this.areaVm.town = this.areaVm.village = '';
    } else {
      this.areaVm.province = v.length >= 2 ? v.substring(0, 2) : '';
      this.areaVm.city = v.length >= 4 ? v.substring(0, 4) : '';
      this.areaVm.area = v.length >= 6 ? v.substring(0, 6) : '';
      this.areaVm.town = v.length >= 9 ? v.substring(0, 9) : '';
      this.areaVm.village = v.length >= 12 ? v.substring(0, 12) : '';
    }
  }

  @Watch('myvalue')
  OnChangeMyvalue(v: string) {
    this.$nextTick(() => {
      this.$emit('update:modelValue', this.myvalue);
    });
    // 如果myvalue有变化就进行清理数据源
    this.clearAreaSource();
  }

  @Watch('areaVm.province')
  OnChangeProvince(v: string, o) {
    if (o !== '') {
      this.areaVm.city = '';
      this.areaVm.area = '';
      this.areaVm.town = '';
      this.areaVm.village = '';
    }
    this.clearAreaSource();
    // 改变后只触发下一个等级下拉框重新加载数据源
    if (!isNullOrWhiteSpece(v)) {
      this._getCity(v);
    }
  }

  @Watch('areaVm.city')
  OnChangeCity(v: string, o) {
    if (o !== '') {
      this.areaVm.area = '';
      this.areaVm.town = '';
      this.areaVm.village = '';
    }
    this.clearAreaSource();
    if (!isNullOrWhiteSpece(v)) {
      this._getArea(v);
    }
  }

  @Watch('areaVm.area')
  OnChangeArea(v: string, o) {
    if (o !== '') {
      this.areaVm.town = '';
      this.areaVm.village = '';
    }
    this.clearAreaSource();
    if (!isNullOrWhiteSpece(v)) {
      this._getTown(v);
    }
  }

  @Watch('areaVm.town')
  OnChangeTown(v: string, o) {
    if (o !== '') {
      this.areaVm.village = '';
    }
    this.clearAreaSource();
    if (!isNullOrWhiteSpece(v)) {
      this._getVillage(v);
    }
  }

  getValue() {
    if (this.areaVm.village.length > 0 && parseInt(this.areaVm.village) > 0) {
      return this.areaVm.village;
    }
    if (this.areaVm.town.length > 0 && parseInt(this.areaVm.town) > 0) {
      return this.areaVm.town;
    }
    if (this.areaVm.area.length > 0 && parseInt(this.areaVm.area) > 0) {
      return this.areaVm.area;
    }
    if (this.areaVm.city.length > 0 && parseInt(this.areaVm.city) > 0) {
      return this.areaVm.city;
    }
    if (this.areaVm.province.length > 0 && parseInt(this.areaVm.province) > 0) {
      return this.areaVm.province;
    }
    return '';
  }

  _getProvince() {
    return AreaSrc.getProvince().then((res) => {
      if (!isNullOrWhiteSpece(this.firstnode)) {
        res.unshift({
          ProvinceCode: '',
          ProvinceName: this.firstnode
        });
      }
      this.source.provinceLst = res;
    });
  }

  _getCity(value: string) {
    return AreaSrc.getCity(value).then((result) => {
      if (this.firstnode) {
        result.unshift({
          CityCode: '',
          CityName: this.firstnode
        });
      }
      this.source.cityLst = result;
    });
  }

  _getArea(value: string) {
    return AreaSrc.getArea(value).then((result) => {
      if (this.firstnode) {
        result.unshift({
          AreaCode: '',
          AreaName: this.firstnode
        });
      }
      this.source.areaLst = result;
    });
  }

  _getTown(value: string) {
    return AreaSrc.getTown(value).then((result) => {
      if (this.firstnode) {
        result.unshift({
          TownCode: '',
          TownName: this.firstnode
        });
      }
      this.source.townLst = result;
    });
  }

  _getVillage(value: string) {
    return AreaSrc.getVillage(value).then((result) => {
      if (this.firstnode) {
        result.unshift({
          VillageCode: '',
          VillageName: this.firstnode
        });
      }
      this.source.villageLst = result;
    });
  }
}
</script>

<template>
  <div>
    <div style="display: flex">
      <div style="flex: 1 1 0%">
        <el-select
          v-model="areaVm.province"
          label="省"
          stext="ProvinceName"
          svalue="ProvinceCode"
          lwidth="54"
          @change="provinceChange"
        >
          <el-option
            v-for="item in source.provinceLst"
            :key="item.ProvinceCode"
            :label="item.ProvinceName"
            :value="item.ProvinceCode"
          />
        </el-select>
      </div>
      <div style="flex: 1 1 0%">
        <el-select v-model="areaVm.city" :source="source.cityLst" lwidth="54" @change="cityChange">
          <el-option
            v-for="item in source.cityLst"
            :key="item.CityCode"
            :label="item.CityName"
            :value="item.CityCode"
          />
        </el-select>
      </div>
      <div v-if="showLevel >= 3" style="flex: 1 1 0%">
        <el-select
          v-model="areaVm.area"
          :source="source.areaLst"
          stext="AreaName"
          svalue="AreaCode"
          lwidth="54"
          @change="areaChange"
        >
          <el-option
            v-for="item in source.areaLst"
            :key="item.AreaCode"
            :label="item.AreaName"
            :value="item.AreaCode"
          />
        </el-select>
      </div>
      <div v-if="showLevel >= 4" style="flex: 1 1 0%">
        <el-select v-model="areaVm.town" :source="source.townLst" lwidth="54" @change="townChange">
          <el-option
            v-for="item in source.townLst"
            :key="item.TownCode"
            :label="item.TownName"
            :value="item.TownCode"
          />
        </el-select>
      </div>
      <div v-if="showLevel >= 5" style="flex: 1 1 0%">
        <el-select v-model="areaVm.village" :source="source.villageLst" lwidth="54">
          <el-option
            v-for="item in source.villageLst"
            :key="item.VillageCode"
            :label="item.VillageName"
            :value="item.VillageCode"
          />
        </el-select>
      </div>
    </div>
  </div>
</template>
